<?php

//Controller abstract base class.
//All controllers should inherit from this class.

/**
 * @property-read ControllerManager $CMM The singleton to the Controller Chain Manager
 * @property-read view $view The current view object
 * @abstract
 */
abstract class Controller {
    public $type = __CLASS__;
    /**
     * @var view The singleton of the current View object
     */
    protected $view;
    /**
     * @var ControllerManager A singleton reference to the controller manager
     */
    protected $CMM;
    
    /**
     * Constructor
     * Creates and references a new view for the controller to use as $controller->View;
     * Sets up a reference to the CManager as $controller->CMM;
     * @final
     * @return null;
     */
    final public function __construct() {
        $VM = ViewManager::Inst();
        $this->view = $VM;
        $this->CMM  = ControllerManager::Inst();
        
        $this->initialise(); //Call the init function;
        //We use the derived initialise function rather than add to the constructor 
        //on derived classes just in case a constructor isn't called with parent::construct;
        return;
    }

    /**
     * A magic method to ensure thiat if a controllers action is called which
     * doesn't exist, it won't throw an error. Instead it will return false so
     * we can pick up the error and throw our own error which the user can understand.
     * @param string $data The name of the function which doesn't exist being called.
     * @param mixed $argument Any additional parameters
     */
    final public function __call($data, $argument) {
        $this->CMM->registerControllerIntoChain('system', 'notFound');
        return false;
    }


    /**
     * Tests to see if the current user is logged in and if they have access
     * to the specific role
     *
     * @param string $authorization The role name
     * @return bool Whether or not the user is logged in
     */
    final public function isStaffAuthorized($authorization) {
        $session = Session::inst();
        if (! $session->authenticateSession())
        {
            return false;
        }
        $user = $session->user;
        $user->link();
        return $user->hasRoleAccess($authorization);
    }
    
    /**
     * Returns the user logged in, null if not logged in at all
     * 
     * @return Staff The User
     */
    final public function getAuthorizedUser() {
        $session = Session::inst();
        $session->user->link();
        return $session->user;
    }

    final public function displayTreeStructure($args) {
        $this->view->registerTemplate("trees/structure.header");
        foreach ($args as $link => $display) {
            $this->view->registerTemplate("trees/structure.view");
            $this->view->registerVariable($display, "display");
            $this->view->registerVariable($link, "link");
        }
        $this->view->registerTemplate("trees/structure.footer");
    }


    /**
     * Initialisation function for derived classes to define.
     * @return null;
     */
    abstract protected function initialise();
}

?>